// Copyright (C) 2023 Storj Labs, Inc.
// See LICENSE for copying information.

<template>
    <template v-if="!isSuccess">
        <v-row class="ma-0" justify="space-between" align="center">
            <v-col class="px-0" cols="auto">
                <span class="font-weight-bold">Activate your plan</span>
            </v-col>
            <v-col class="px-0" cols="auto">
                <v-btn density="compact" color="success" variant="tonal" icon>
                    <v-icon :icon="mdiCheckOutline" />
                </v-btn>
            </v-col>
        </v-row>

        <v-row class="ma-0" align="center">
            <v-col class="px-0" cols="9">
                <div class="pt-4">
                    <p class="font-weight-bold">{{ plan.title }} <span v-if="plan.activationSubtitle"> / {{ plan.activationSubtitle }}</span></p>
                </div>

                <div>
                    <!-- eslint-disable-next-line vue/no-v-html -->
                    <p v-html="plan.activationDescriptionHTML" />
                </div>
            </v-col>
            <v-col v-if="plan.activationPriceHTML" class="px-0" cols="3">
                <!-- eslint-disable-next-line vue/no-v-html -->
                <p class="font-weight-bold" v-html="plan.activationPriceHTML" />
            </v-col>
        </v-row>

        <div v-if="!isFree" class="my-4">
            <p class="text-caption mb-2">Add Card Info</p>
            <StripeCardElement
                v-if="paymentElementEnabled"
                ref="stripeCardInput"
            />
            <StripeCardInput
                v-else
                ref="stripeCardInput"
            />
        </div>

        <div class="py-4">
            <v-btn
                block
                :color="plan.type === 'partner' ? 'success' : 'primary'"
                :loading="loading"
                @click="onActivateClick"
            >
                <template v-if="plan.type !== 'free'" #prepend>
                    <v-icon :icon="mdiLock" />
                </template>

                {{ plan.activationButtonText || ('Activate ' + plan.title) }}
            </v-btn>
        </div>

        <div class="pb-4">
            <v-btn
                block
                variant="outlined"
                color="grey-lighten-1"
                :disabled="loading"
                @click="emit('back')"
            >
                Back
            </v-btn>
        </div>
    </template>

    <template v-else>
        <v-row class="ma-0" justify="center" align="center">
            <v-col cols="auto">
                <v-btn density="comfortable" color="success" variant="tonal" icon>
                    <v-icon :icon="mdiCheckOutline" />
                </v-btn>
            </v-col>
        </v-row>

        <h1 class="text-center">Success</h1>

        <p class="text-center mb-4">Your plan has been successfully activated.</p>

        <v-alert
            class="mb-4"
            type="success"
            variant="tonal"
        >
            <template #prepend>
                <v-icon :icon="mdiCheckOutline" />
            </template>
            <template #text>
                <p class="font-weight-bold">
                    {{ plan.title }}
                </p>
                <p v-if="plan.activationSubtitle">{{ plan.activationSubtitle }}</p>
            </template>
            <template #append>
                <span>Activated</span>
            </template>
        </v-alert>

        <v-btn
            color="success"
            block
            @click="emit('close')"
        >
            Continue
        </v-btn>
    </template>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';
import { VAlert, VBtn, VCol, VIcon, VRow } from 'vuetify/components';
import { useTheme } from 'vuetify';
import { mdiCheckOutline, mdiLock } from '@mdi/js';

import { PricingPlanInfo, PricingPlanType } from '@/types/common';
import { useNotify } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore';
import { useBillingStore } from '@/store/modules/billingStore';
import { useConfigStore } from '@/store/modules/configStore';

import StripeCardElement from '@/components/StripeCardElement.vue';
import StripeCardInput from '@/components/StripeCardInput.vue';

interface StripeForm {
    onSubmit(): Promise<string>;
}

const configStore = useConfigStore();
const billingStore = useBillingStore();
const usersStore = useUsersStore();

const router = useRouter();
const notify = useNotify();
const theme = useTheme();

const isSuccess = ref<boolean>(false);

const stripeCardInput = ref<StripeForm | null>(null);

const props = withDefaults(defineProps<{
    plan?: PricingPlanInfo;
}>(), {
    plan: () => new PricingPlanInfo(),
});

const emit = defineEmits<{
    back: [];
    close: [];
    success: []; // emit this for parents that have custom success steps.
}>();

const loading = defineModel<boolean>('loading');

/**
 * Indicates whether stripe payment element is enabled.
 */
const paymentElementEnabled = computed(() => {
    return configStore.state.config.stripePaymentElementEnabled;
});

/**
 * Returns whether current plan is a free pricing plan.
 */
const isFree = computed((): boolean => {
    return props.plan?.type === PricingPlanType.FREE;
});

/**
 * Applies the selected pricing plan to the user.
 */
async function onActivateClick() {
    if (loading.value || !props.plan) return;

    if (isFree.value) {
        emit('success');
        isSuccess.value = true;
        return;
    }

    if (!stripeCardInput.value) return;

    loading.value = true;
    try {
        const response = await stripeCardInput.value.onSubmit();
        await onCardAdded(response);
    } catch (error) {
        notify.notifyError(error);
    }
    loading.value = false;
}

/**
 * Adds card after Stripe confirmation.
 * @param res - the response from stripe. Could be a token or a payment method id.
 * depending on the paymentElementEnabled flag.
 */
async function onCardAdded(res: string): Promise<void> {
    if (!props.plan) return;
    try {
        if (props.plan.type === PricingPlanType.PARTNER) {
            await billingStore.purchasePricingPackage(res, paymentElementEnabled.value);
        } else {
            paymentElementEnabled.value ? await billingStore.addCardByPaymentMethodID(res) : await billingStore.addCreditCard(res);
        }
        emit('success');
        isSuccess.value = true;

        // Fetch user to update paid tier status
        usersStore.getUser().catch((_) => {});
        // Fetch cards to hide paid tier banner
        billingStore.getCreditCards().catch((_) => {});
    } catch (error) {
        notify.notifyError(error);
    }
}
</script>
